home *** CD-ROM | disk | FTP | other *** search
- /**********************************************************************
- **
- ** MList [/t tabsize] [/b linebias] fname [fname [...]]
- **
- ** Create a numbered listing with intelligent line wrap, titles and
- ** pagination
- **
- ** Author : Dan Rhea
- ** Date : 07/07/88
- ** History : 07/07/88 v1.00 - Started coding
- ** 07/17/88 v1.01 - Added the /t option
- ** Bumped buffer size up to 255
- ** Added code to finish of a partial page
- ** 07/13/88 v1.02 - Added full title and footer centering
- ** 07/28/88 v1.03 - Added error tab check and set default tab
- ** to 8
- ** Fixed starting line of first page
- ** 08/03/88 v1.04 - Fixed header and footer positions
- ** Added a blank line after the header and
- ** before the footer so entire listing is
- ** visible if it is kept in a binder
- ** Added total lines printed
- ** 08/22/88 v1.05 - Added code to finish off partial lines
- ** when EOF is hit (i.e. last line ends in
- ** EOF not a newline)
- ** 08/29/88 v1.06 - By request... a warm fuzzy every 100
- ** lines Added a screen centering routine
- ** Some general output cleanup...
- ** Center all the normal screen output...
- ** 09/01/88 v1.07 - The ATARI version! (conditional code
- ** included)
- ** 09/04/88 v1.08 - Minor changes to make the source file
- ** compile and link in either environment
- ** without changes
- ** 11/07/88 v1.09 - Re-sized page length to work well with a
- ** typical laser printer.
- ** 11/10/88 v1.10 - Re-worked the centering routines to
- ** reduce a lot of redundant code/routines.
- ** 03/29/89 v1.11 - Added a line number bias option [/b n]
- ** 05/01/89 v1.12 - Changed tab logic to use modulis
- ** calculation
- ** 05/09/89 v1.13 - Added an inhibit line number option [/l]
- ** 08/26/89 v1.14 - Corrected count error caused by bias
- ** 11/24/89 v1.15 - Corrections to get Atari version in sync
- **
- ** Microsoft C 5.1 Compile and link directive (MS-DOS Version)
- **
- ** CL /AL /Ox \MSC\SRC\MLIST.C \MSC\LIB\SETARGV.OBJ /link /NOE
- **
- ** Mark Williams C 2.0 CC Directive (Atari GEMDOS Version)
- **
- ** CC -v MLIST.C
- **
- ** Copyright (c) 1988 by Dan Rhea, All rights reserved
- ** program may be copied freely,
- ** but never sold or rented
- **
- **********************************************************************/
-
- #include "stdio.h"
- #if GEMDOS
- #include "osbind.h"
- #else
- #include "string.h"
- #include "malloc.h"
- #endif
-
- #define FALSE 0
- #define TRUE 1
- #define WIDTH 80
- #define TAB 0x09
- #define BLANK 0x20
- #define BSIZE 255
- #define PAGELEN 57
-
- int ch; /* Character in process */
- int cntr; /* Tab expansion counter */
- int last_char; /* Last character processed */
- int tab_set; /* Tab expansion value */
- unsigned int ocount; /* Output buffer line counter */
-
- main (argc, argv)
- int argc;
- char **argv;
- {
-
- /* Define a bunch of stuff... */
- FILE *fin; /* File input stream */
- #if GEMDOS
- FILE *stdprn; /* Printer stream */
- #endif
- unsigned char *lineout; /* Text output buffer */
- unsigned char *title; /* Title buffer */
- unsigned char *footer; /* Footer buffer */
- unsigned char *junk; /* Scratch buffer */
- unsigned char *to_screen; /* Screen line buffer */
- unsigned char *lptr; /* Text buffer pointer */
- unsigned char *sptr; /* Screen buffer pointer */
- unsigned int c; /* Current character */
- unsigned int i; /* Loop index */
- unsigned int wrap; /* Line wrap flag */
- unsigned int lcount; /* Output line counter (for display) */
- unsigned int pcount; /* Page counter (for display) */
- unsigned int ccount; /* Character counter (internal) */
- unsigned int tcount; /* Real line counter (internal) */
- unsigned int acount; /* All lines printed counter */
- unsigned int xcount; /* Adjusted counter */
- unsigned int pad; /* Lines to pad out last page */
- unsigned int tof; /* Top of form flag */
- unsigned int first1; /* First file flag */
- unsigned int fuzzy; /* Warm fuzzy variable */
- unsigned int l_bias; /* Line counter bias (usually 1) */
- unsigned int l_num; /* Line number flag F=Inhibit */
- unsigned int l_wid; /* Text line width (71 or 80) */
-
- /* Allocate buffers */
- lineout = (unsigned char *) malloc(BSIZE * sizeof(unsigned char));
- title = (unsigned char *) malloc(BSIZE * sizeof(unsigned char));
- footer = (unsigned char *) malloc(BSIZE * sizeof(unsigned char));
- junk = (unsigned char *) malloc(BSIZE * sizeof(unsigned char));
- to_screen = (unsigned char *) malloc(WIDTH * sizeof(unsigned char));
-
- #if GEMDOS
-
- /* Open the printer */
- printf ("\033E");
- if ((stdprn = fopen ("PRN:","w")) == NULL) {
- center_scr ("\007Error: Unable to open printer.", TRUE);
- go_away(1);
- }
- #endif
-
- /* Init stuff */
- last_char = BLANK;
- ch = BLANK;
- cntr = FALSE;
- tab_set = 8;
- lptr = lineout;
- sptr = to_screen;
- first1 = TRUE;
- acount = 0;
- l_bias = 1;
- l_num = TRUE;
- l_wid = 71;
- printf ("\n");
-
- /* Greetings earth person... */
- center_scr ("MLIST v1.15 (c) Copyright 1988, 1989 by Dan Rhea,",
- WIDTH, TRUE);
- center_scr ("All rights reserved.",
- WIDTH, TRUE);
- center_scr (" ",
- WIDTH, TRUE);
- #ifndef GEMDOS
- center_scr ("Provided courtesy of DATA BASE Computers and Software",
- WIDTH, TRUE);
- center_scr ("Plantation, FL (305)474-3355",
- WIDTH, TRUE);
- center_scr (" ",
- WIDTH, TRUE);
- #endif
- center_scr ("This program can be freely copied but not sold.",
- WIDTH, TRUE);
- center_scr (" ",
- WIDTH, TRUE);
-
- /* Make sure we've got something to do */
- if (argc <= 1) {
- #if GEMDOS
- printf ("\007");
- center_scr ("usage: MLIST [-t tab] [-b bias] [-l] file [file [...]]", WIDTH, TRUE);
- #else
- printf ("\007");
- center_scr ("usage: MLIST [/t tab] [/b bias] [/l] file [file [...]]", WIDTH, TRUE);
- #endif
- center_scr (" ", WIDTH, TRUE);
- center_scr ("/t = Tab stop change option. ", WIDTH, TRUE);
- center_scr ("/b = Bias line number option. ", WIDTH, TRUE);
- center_scr ("/l = Inhibit line numbers option. ", WIDTH, TRUE);
- center_scr ("tab = Tab expansion of 2 to 255 (defaults to 8). ", WIDTH, TRUE);
- center_scr ("bias = Value added to line counter (defaults to 1). This is ", WIDTH, TRUE);
- center_scr (" most usefull for printing file fragments. ", WIDTH, TRUE);
- center_scr ("file = Full path name of files to print (supports wildcards)", WIDTH, TRUE);
- go_away(1);
- }
-
- /* Loop once for each file supplied via the command line */
- while (--argc > 0) {
-
- /* Open file and handle an error if need be */
- if ((fin = fopen (*++argv, "r")) == NULL) {
-
- /* If the file open falied, see if this is an option */
- if ((*argv)[0] == '-'|| (*argv)[0] == '/') {
-
- /* See if it's a tab option */
- if ((*argv)[1] == 'T' || (*argv)[1] == 't') {
- tab_set = atoi (*++argv);
- argc--;
- if (tab_set < 2 || tab_set > 255) {
- sprintf (sptr, "\007Error: Tab out of range (2-255), ");
- center_scr (sptr, WIDTH, TRUE);
- sptr = to_screen;
- sprintf (sptr, "forced to tab of 8.");
- center_scr (sptr, WIDTH, TRUE);
- sptr = to_screen;
- tab_set = 8;
- }
- } else {
-
- /* See if it's a line bias option */
- if ((*argv)[1] == 'B' || (*argv)[1] == 'b') {
- l_bias = atoi (*++argv);
- argc--;
- if ((l_bias < 1) || (l_bias > 9999999L)) {
- sprintf (sptr, "\007Error: Line bias out of range (1-9999999), ");
- center_scr (sptr, WIDTH, TRUE);
- sptr = to_screen;
- sprintf (sptr, "forced to default of 1.");
- center_scr (sptr, WIDTH, TRUE);
- sptr = to_screen;
- l_bias = 1;
- }
- } else {
-
- /* See if we have a line number inhibit */
- if (((*argv)[1] == 'L') || ((*argv)[1] == 'l')) {
- l_num = FALSE;
- l_wid = 80;
- } else {
-
- /* Option? I don know dis stenkin option... */
- sprintf (sptr, "\007Error: Invalid command line argument.");
- center_scr (sptr, WIDTH, TRUE);
- sptr = to_screen;
-
- }
- }
- }
- } else {
-
- /* No it's just your plain old everyday non-existant file */
- sprintf (sptr, "\007Error: Unable to open %s.", *argv);
- center_scr (sptr, WIDTH, TRUE);
- sptr = to_screen;
- }
-
- } else {
-
- /* Initialize things since we have a new file to do */
- ccount = tcount = ocount = 0;
- pcount = 1;
- lcount = l_bias;
- sptr = to_screen;
- if (l_num == TRUE) {
- l_wid = 71;
- } else {
- l_wid = 79;
- }
-
- /* Let the world know of our dirty deeds */
- sprintf (sptr, "Printing %s", *argv);
- center_scr (sptr, WIDTH, FALSE);
- sptr = to_screen;
-
- /* Print a title on the listing */
- strcpy (title, "File : ");
- sprintf (junk, "%s", *argv);
- strcat (title, junk);
- tcount = 5;
- if (first1) {
- fprintf (stdprn, "\n\n");
- } else {
- fprintf (stdprn, "\n");
- }
- center_prn (stdprn, title, WIDTH, TRUE);
- if (first1) {
- fprintf (stdprn, "\n\n");
- first1 = FALSE;
- } else {
- fprintf (stdprn, "\n\n");
- }
-
- /* Initialize text buffer for output */
- lptr = lineout;
- for (i = 0; i <= BSIZE; i++) {
- *lptr = BLANK;
- lptr++;
- }
- lcount = l_bias;
- lptr = lineout;
-
- /* Start grabbing data from the input file */
- wrap = FALSE;
- c = get_stuff (fin);
- while (c != EOF) {
- ccount = ccount + 1;
-
- /* Output the line if we get a newline */
- if (c == '\n') {
-
- /* Process a wrapped line */
- if (ocount > l_wid && wrap == TRUE) {
- if (l_num == TRUE) {
- fprintf (stdprn, "------> %-72.72s\n", lineout);
- } else {
- fprintf (stdprn, "%-80.80s\n", lineout);
- }
- } else {
-
- /* Otherwise show a normal numbered one */
- if (l_num == TRUE) {
- fprintf (stdprn, "%7d %-72.72s\n", lcount, lineout);
- } else {
- fprintf (stdprn, "%-80.80s\n", lineout);
- }
- }
-
- /* Set things up for the next line */
- wrap = FALSE;
- ccount = ocount = 0;
- fflush (stdprn);
- lptr = lineout;
- for (i = 0; i <= BSIZE; i++) {
- *lptr = BLANK;
- lptr++;
- }
- lptr = lineout;
- tcount++;
- lcount++;
-
- /* Put a warm fuzzy on the screen every 10 lines */
- if (l_bias == 1) {
- xcount = lcount;
- } else {
- xcount = lcount - l_bias;
- }
- if (l_bias == 1) {
- fuzzy = lcount / 10;
- } else {
- fuzzy = (lcount - l_bias) / 10;
- }
- if ((fuzzy * 10) == xcount) {
- sprintf (sptr, "Printing %s. %d lines so far.", *argv, xcount);
- center_scr (sptr, WIDTH, FALSE);
- sptr = to_screen;
- }
- } else {
-
- /* Do a clean line wrap if the line get's too long */
- if (ocount > l_wid && wrap == FALSE) {
- wrap = TRUE;
- if (l_num == TRUE) {
- fprintf (stdprn, "%7d %-72.72s\n", lcount, lineout);
- } else {
- fprintf (stdprn, "%-80.80s\n", lineout);
- }
- tcount++;
-
- /* Start the next line to be output */
- lptr = lineout;
- for (i = 0; i <= BSIZE; i++) {
- *lptr = BLANK;
- lptr++;
- }
- lptr = lineout;
- ccount = 0;
- *lptr = c;
- lptr++;
- ocount++;
- } else {
-
- /* Otherwise just put the character into the output
- ** buffer */
- *lptr = c;
- lptr++;
- ocount++;
- }
- }
-
- /* If end of page do footer and advance a page */
- if (tcount >= PAGELEN) {
- strcpy (footer, " \0");
- strcpy (footer, "Page : ");
- strcpy (junk, " \0");
- sprintf (junk, "%5d\014", pcount);
- strcat (footer, junk);
- fprintf (stdprn, "\n\n");
- center_prn (stdprn, footer, WIDTH, FALSE);
- tcount = 0;
- tof = TRUE;
- }
-
- /* Grab another character */
- c = get_stuff (fin);
-
- /* Do a top of form if needed and not EOF */
- if (tof == TRUE && c != EOF) {
- pcount++;
- tcount = 5;
- fprintf (stdprn, "\n");
- center_prn (stdprn, title, WIDTH, TRUE);
- fprintf (stdprn, "\n\n");
- tof = FALSE;
- }
- }
-
- /* Finish off any partial line that may be left over */
- if (ccount > 0) {
- if (wrap == TRUE) {
- if (l_num == TRUE) {
- fprintf (stdprn, "------> %-72.72s\n", lineout);
- } else {
- fprintf (stdprn, "%-80.80s\n", lineout);
- }
- wrap = FALSE;
- } else {
- if (l_num == TRUE) {
- fprintf (stdprn, "%7d %-72.72s\n", lcount, lineout);
- } else {
- fprintf (stdprn, "%-80.80s\n", lineout);
- }
- }
- fflush (stdprn);
- tcount++;
- lcount++;
- }
-
- /* Finish the page and force a form feed between files */
- lcount--;
- if (l_bias == 1) {
- xcount = lcount;
- } else {
- xcount = lcount - l_bias;
- }
- sprintf (sptr, "Printing %s done, %d lines printed.", *argv, xcount);
- center_scr (sptr, WIDTH, FALSE);
- sptr = to_screen;
- printf ("\n");
- if (l_bias == 1) {
- acount = acount + lcount;
- } else {
- acount = acount + (lcount - l_bias);
- }
- if (tcount != 0) {
-
- /* Purge line buffer if we have a partial line (EOF without
- ** EOL) */
- pad = PAGELEN - tcount;
- for (i = 0; i <= pad; i++) {
- fprintf (stdprn, "\n");
- }
- fprintf (stdprn, "\n");
- strcpy (footer, " \0");
- strcpy (footer, "Page : ");
- strcpy (junk, " \0");
- sprintf (junk, "%5d\014", pcount);
- strcat (footer, junk);
- center_prn (stdprn, footer, WIDTH, FALSE);
- fflush (stdprn);
- }
- fclose (fin);
- l_bias = 1;
- }
- }
-
- /* Say goodnight... */
- printf ("\n");
- sprintf (sptr, "Total lines printed was %d.", acount);
- center_scr (sptr, WIDTH, TRUE);
- sptr = to_screen;
- center_scr ("Done!", WIDTH, TRUE);
- go_away(0);
- }
-
- /****************************************************************************
- ** ret = get_stuff (stream) - Simply reads characters from the file stream
- ** and returns it as an integer character. If the tab expansion is on and a
- ** tab character is detected it will be expanded with spaces to the requested
- ** size
- ****************************************************************************/
-
- int
- get_stuff (st)
-
- FILE *st; /* Input stream handle */
-
- {
-
- /* See if we are expanding a tab character */
- if (last_char == TAB) {
-
- /* Finish up the expansion if we reach tab size + 1 */
- if ((ocount % tab_set) == 0) {
- ch = getc (st);
- cntr = FALSE;
- last_char = ch;
- } else {
-
- /* Otherwise substitute a blank */
- ch = BLANK;
- }
- } else {
-
- /* If we aren't expanding tabs then simply pass on the
- ** character */
- ch = getc (st);
- last_char = ch;
- cntr = FALSE;
- }
-
- /* See if the current character is a tab, if so start expansion */
- if (ch == TAB) {
- ch = BLANK;
- cntr = TRUE;
- }
-
- /* Return with expansion or a new character */
- return (ch);
- }
-
- /****************************************************************************
- ** center_prn (strm, text, width, flag) - Centers "text" within "width" and
- ** sends the result to stdprn. If flag is true end with a \n.
- ****************************************************************************/
-
- int
- center_prn (strm, text, width, flag)
-
- FILE *strm;
- unsigned char *text;
- int width;
- int flag;
- {
- int i; /* Intermediate input buffer */
- int to_pad; /* Padding buffer */
-
- /* Determine the length of "text" and use it to calculate the padding
- ** we need to do, pad the line and output the text */
- to_pad = (width - strlen (text)) / 2;
- for (i = 0; i <= to_pad; i++)
- fprintf (strm, " ");
- fprintf (strm, "%s", text);
- if (flag == TRUE) {
- fprintf (strm, "\n");
- }
- return (0);
- }
-
- /****************************************************************************
- ** center_scr (text, width, flag) - Centers "text" within "width" and sends
- ** the result to stdout.
- ****************************************************************************/
-
- int
- center_scr (text, width, flag)
- unsigned char *text;
- int width;
- int flag;
- {
- int i; /* Intermediate character */
- int to_pad; /* Padding buffer */
-
- /* Determine the length of "text" and use it to calculate the
- ** padding we need to do, pad the line and output the text */
- to_pad = (width - strlen (text)) / 2;
- printf ("\r");
- for (i = 0; i <= to_pad; i++)
- printf (" ");
- printf ("%s", text);
- if (flag == TRUE) {
- printf ("\n");
- }
- return (0);
- }
-
- /****************************************************************************
- ** go_away (exitval) - Exit with exitval but if this is Atari GEMDOS then
- ** prompt for a character before returning to shell or desktop
- ****************************************************************************/
-
- go_away (exitval)
- int exitval;
- {
-
- int c; /* Scratch input byte */
- #if GEMDOS
- center_scr (" ", WIDTH, TRUE);
- center_scr ("Press Return/Enter for the desktop or shell.", WIDTH, TRUE);
- c = getc (stdin);
- #endif
- exit (exitval);
- }
-